import { useEffect, useRef, useState } from 'react';
import type { TypedKey } from '../context/types';
import { shallowEqual } from '../utils/shallowEqual';
import { useListen } from './useListen';

export function useSelect<T, R>(
  key: TypedKey<T>,
  selector: (value: T) => R,
  equalityFn: (a: R, b: R) => boolean = shallowEqual,
): R {
  const [value] = useListen(key);
  const [selected, setSelected] = useState(() => selector(value));
  const prevSelectedRef = useRef(selected);

  useEffect(() => {
    const newSelected = selector(value);
    if (!equalityFn(prevSelectedRef.current, newSelected)) {
      setSelected(newSelected);
      prevSelectedRef.current = newSelected;
    }
  }, [value, selector, equalityFn]);

  return selected;
}
